RoboMaster视觉笔记CMake(六) Compile Flags
本CMake系列是依据github上的cmake-examples进行翻译总结。同时对于不懂的地方进行总结与标注。希望本系列能节省你学习CMake的时间。
学习方式是在实践中利用github上的example学习,同时对于不懂的地方主要通过翻译官方手册学习,其次是查找博客上的私人理解。
因为每一个example都是一个工程,所以讲解时会利用文件树解释每一个文件里的语法。
英文github地址:https://github.com/ttroy50/cmake-examples
CMake英文官方教程: https://cmake.org/cmake/help/latest/guide/tutorial/index.html
[TOC]
首先说一下什么是编译标志(或者 叫编译选项)。可执行文件的生成离不开编译和链接,那么如何编译,比如编译时使用C++的哪一个标准?这些编译设置都在CMAKE_CXX_FLAGS变量中。(C语言编译选项是CMAKE_C_FLAGS)
设置的方法总共有三种,分别为本文2.1、2.2、以及2.3
一 文件树
├── CMakeLists.txt
├── main.cpp
1.1 main.cpp
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "Hello Compile Flags!" << std::endl;
// only print if compile flag set
#ifdef EX2
std::cout << "Hello Compile Flag EX2!" << std::endl;
#endif
#ifdef EX3
std::cout << "Hello Compile Flag EX3!" << std::endl;
#endif
return 0;
}
1.2 CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
#强制设置默认C++编译标志变量为缓存变量,如CMake(五) build type所说,该缓存变量被定义在文件中,相当于全局变量,源文件中也可以使用这个变量
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
project (compile_flags)
add_executable(cmake_examples_compile_flags main.cpp)
#为可执行文件添加私有编译定义
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
#命令的具体解释在二 CMake解析中,这里的注释只说明注释后每一句的作用
二 CMake解析
2.1 设置每个目标编译标志
在现代CMake中设置C ++标志的推荐方法是专门针对某个目标(target)设置标志,可以通过target_compile_definitions()函数设置某个目标的编译标志。
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
如果这个目标是一个库(cmake_examples_compile_flags),编译器在编译目标时添加定义-DEX3 ,并且选择了范围PUBLIC或INTERFACE,该定义-DEX3也将包含在链接此目标(cmake_examples_compile_flags)的所有可执行文件中。 注意,本语句使用了PRIVATE,所以编译选项不会传递。
对于编译器选项,还可以使用target_compile_options()函数。 (此处谢谢github用户HamsterCoderSim的更正)
target_compile_options(<target> [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
是给 target
添加编译选项, target
指的是由 add_executable()
产生的可执行文件或 add_library()
添加进来的库。<INTERFACE|PUBLIC|PRIVATE>
指的是[items...]
选项可以传播的范围, PUBLIC and INTERFACE
会传播 <target>
的 INTERFACE_COMPILE_DEFINITIONS 属性, PRIVATE and PUBLIC
会传播 target
的 COMPILE_DEFINITIONS 属性。
2.2 设置默认编译标志
默认的CMAKE_CXX_FLAGS为空或包含适用于构建类型的标志。 要设置其他默认编译标志,如下使用:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
强制设置默认C++编译标志变量为缓存变量,如CMake(五) build type所说,该缓存变量被定义在文件中,相当于全局变量,源文件中也可以使用这个变量。这个变量原本包含的参数仍然存在,只是添加了EX2。
CACHE STRING "Set C++ Compiler Flags" FORCE
命令是为了强制将CMAKE_CXX_FLAGS变量 放到CMakeCache.txt文件中
"${CMAKE_CXX_FLAGS} -DEX2"
这个字符串可以保留原有的CMAKE_CXX_FLAGS中的参数,额外添加了一个EX2参数。注意写法:空格,并且参数前加了-D
类似设置CMAKE_CXX_FLAGS,还可以设置其他选项:
- 设置C编译标志: CMAKE_C_FLAGS
- 设置链接标志:CMAKE_LINKER_FLAGS.
2.3 设置CMake标志
与构建类型类似,可以使用以下方法设置全局C 编译器标志。
利用ccmake或者gui
在cmake命令行中:
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
2.4 区别
- 2.2方法的设置CMAKE_C_FLAGS和CMAKE_CXX_FLAGS将为该目录或所有包含的子目录中的所有目标全局设置一个编译器标志。 现在不建议使用该方法,首选使用target_compile_definitions函数。
- 2.1方法是被建议的,只为这个目标设置编译选项 。
- 2.3设置的也是全局编译器选项。
三 构建示例
$ mkdir build
$ cd build/
$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build
$ make VERBOSE=1
/usr/bin/cmake -H/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags -B/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
make -f CMakeFiles/cmake_examples_compile_flags.dir/build.make CMakeFiles/cmake_examples_compile_flags.dir/depend
make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
cd /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/DependInfo.cmake --color=
Dependee "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/DependInfo.cmake" is newer than depender "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/depend.internal".
Dependee "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/depend.internal".
Scanning dependencies of target cmake_examples_compile_flags
make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
make -f CMakeFiles/cmake_examples_compile_flags.dir/build.make CMakeFiles/cmake_examples_compile_flags.dir/build
make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 1
[100%] Building CXX object CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o
/usr/bin/c++ -DEX2 -o CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/main.cpp
Linking CXX executable cmake_examples_compile_flags
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake_examples_compile_flags.dir/link.txt --verbose=1
/usr/bin/c++ -DEX2 CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o -o cmake_examples_compile_flags -rdynamic
make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 1
[100%] Built target cmake_examples_compile_flags
make[1]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 0
微信公众号
欢迎大家关注我的个人公众号,现阶段主要总结Robomaster相关的计算机视觉知识:Qt,C++,CMake,OpenCV等等 公众号名称:三丰杂货铺